
;;; Required packages: nasm, gcc
;;; compile commands:
;;;     nasm -f elf 06-scanf.asm -o bin/06-scanf.o
;;;     gcc -m32 -o bin/06-scanf bin/06-scanf.o

%define SYSCALL_EXIT 1 ; system call sys_exit
%define INT32_BYTES_SIZE 4
%define FLOAT32_BYTES_SIZE 4
%define STRING_BUFFER_SIZE 32

section .data 
    questionString db "Please enter a string.", 0xa, 0x0
    questionInt32 db "Please enter any integer number.", 0xa, 0x0
    questionFloat32 db "Please enter any decimal number.", 0xa, 0x0

    prompt db "> ", 0x0

    resultMessage db "Entered: string %s, int %d, float %f", 0xa, 0x0

    scanInt32Fmt db "%d", 0x0
    scanFloat32Fmt db "%f", 0x0
    scanStringFmt db "%s", 0x0

section .bss 
    inum resb INT32_BYTES_SIZE
    fnum resb FLOAT32_BYTES_SIZE
    text resb STRING_BUFFER_SIZE

section .text 
    extern scanf 
    extern printf
    global main 

main:
    call printStringPrompt
    call scanString
    call printInt32Prompt
    call scanInt32
    call printFloat32Prompt
    call scanFloat32
    call printMessage
    
    mov eax, SYSCALL_EXIT 
    mov ebx, 0
    int 0x80 

    ret

scanInt32:
    push inum 
    push scanInt32Fmt
    call scanf
    add esp, 8

    ret

scanFloat32:
    push fnum 
    push scanFloat32Fmt
    call scanf
    add esp, 8

    ret

scanString:
    push text
    push scanStringFmt
    call scanf 
    add esp, 8

    ret

printInt32Prompt:
    push questionInt32
    call printf
    add esp, 4

    push prompt
    call printf
    add esp, 4

    ret 

printFloat32Prompt:
    push questionFloat32
    call printf
    add esp, 4

    push prompt
    call printf
    add esp, 4

    ret

printStringPrompt:
    push questionString
    call printf
    add esp, 4

    push prompt
    call printf
    add esp, 4

    ret

printMessage:
    sub esp, 8 ; reserve stack for a float64 (%f requires float64 in printf)
    mov ebx, fnum 
    fld DWORD [ebx] ; load float32 in current stack place (32 bits)
    fstp QWORD [esp] ; store float64 (8087 does the conversion from float32 internally)
    push DWORD [inum]
    push text
    push resultMessage
    call printf
    add esp, 20

    ret